package controllers

import (
	"net/http"

	response "yuanaiproblem/models"
	"yuanaiproblem/models/dto"

	"yuanaiproblem/services"
	"yuanaiproblem/utils"

	"github.com/gin-gonic/gin"
)

// CreatePaper 创建试卷接口
// 入参：请求体（试卷标题、描述、总分、题目ID列表）
// 流程：验证当前用户 -> 解析并校验请求参数 -> 调用服务层创建试卷 -> 返回结果
func CreatePaper(c *gin.Context) {
	// 验证并获取当前用户
	currentUser, err := utils.GetCurrentUser(c)
	if err != nil {
		response.Error(c, http.StatusUnauthorized, err.Error())
		return
	}
	// 解析并校验请求参数
	var req dto.CreatePaperRequest
	if err := utils.BindAndValidate(c, &req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数格式错误: "+err.Error())
		return
	}
	// 调用服务层创建试卷
	createdPaper, err := services.CreatePaper(
		currentUser.ID,
		req.Title,
		req.Description,
		req.TotalScore,
		req.QuestionIDs,
	)
	if err != nil {
		response.Error(c, http.StatusInternalServerError, "创建试卷失败: "+err.Error())
		return
	}
	// 返回成功响应
	response.Success(c, createdPaper, "试卷创建成功")
}

// GetPaperDetail 获取试卷详情
// 入参：路径参数（paper_id）
// 流程：验证当前用户 -> 解析试卷ID -> 调用服务层获取详情 -> 处理错误并返回结果
func GetPaperDetail(c *gin.Context) {
	// 验证并获取当前用户
	currentUser, err := utils.GetCurrentUser(c)
	if err != nil {
		response.Error(c, http.StatusUnauthorized, err.Error())
		return
	}
	// 解析试卷ID
	paperID, err := utils.ParseParamToUint(c, "id")
	if err != nil {
		response.Error(c, http.StatusBadRequest, "无效的试卷ID")
		return
	}
	// 调用服务层获取详情
	paperDetail, err := services.GetPaperDetailByID(paperID, &currentUser)
	if err != nil {
		utils.HandleServiceError(c, err)
		return
	}
	// 返回成功响应
	response.Success(c, paperDetail, "试卷详情获取成功")
}

// GetPaperByUserID 获取当前用户的试卷列表
// 入参：无（从上下文获取当前用户ID）
// 流程：验证当前用户 -> 调用服务层查询用户试卷列表 -> 处理错误并返回结果
func GetPaperByUserID(c *gin.Context) {
	// 验证并获取当前用户
	currentUser, err := utils.GetCurrentUser(c)
	if err != nil {
		response.Error(c, http.StatusUnauthorized, err.Error())
		return
	}
	// 调用服务层查询试卷列表
	paperDetail, err := services.GetPapersByUserID(currentUser.ID)
	if err != nil {
		utils.HandleServiceError(c, err)
		return
	}
	// 返回成功响应
	response.Success(c, paperDetail, "查询成功")
}

// UpdateUserPaperDetail 更新试卷信息
// 入参：路径参数（id）、请求体（待更新的试卷信息）
// 流程：验证当前用户 -> 解析试卷ID -> 解析并校验请求参数 -> 调用服务层更新试卷 -> 返回结果
func UpdateUserPaperDetail(c *gin.Context) {
	// 验证并获取当前用户
	currentUser, err := utils.GetCurrentUser(c)
	if err != nil {
		response.Error(c, http.StatusUnauthorized, err.Error())
		return
	}
	// 解析试卷ID
	paperID, err := utils.ParseParamToUint(c, "id")
	if err != nil {
		response.Error(c, http.StatusBadRequest, err.Error())
		return
	}
	// 解析并校验请求参数
	var req dto.UpdatePaperRequest
	if err := utils.BindAndValidate(c, &req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数格式错误: "+err.Error())
		return
	}
	// 调用服务层更新试卷
	updatedPaper, err := services.UpdatePaper(paperID, req, currentUser.ID, currentUser.Role)
	if err != nil {
		utils.HandleServiceError(c, err)
		return
	}
	// 返回成功响应
	response.Success(c, gin.H{"paper": updatedPaper}, "试卷信息已更新")
}

// DeletePaper 软删除试卷
// 入参：路径参数（id）
// 流程：验证当前用户 -> 解析试卷ID -> 调用服务层执行软删除 -> 处理错误并返回结果
func DeletePaper(c *gin.Context) {
	// 验证并获取当前用户
	currentUser, err := utils.GetCurrentUser(c)
	if err != nil {
		response.Error(c, http.StatusUnauthorized, err.Error())
		return
	}
	// 解析试卷ID
	paperID, err := utils.ParseParamToUint(c, "id")
	if err != nil {
		response.Error(c, http.StatusBadRequest, err.Error())
		return
	}
	// 调用服务层删除试卷
	deletedAt, err := services.DeletePaper(paperID, uint(currentUser.ID), currentUser.Role)
	if err != nil {
		utils.HandleServiceError(c, err)
		return
	}
	// 返回成功响应
	response.Success(c, gin.H{"deleted_at": deletedAt}, "试卷已成功删除")
}

// AddQuestionToPaper 添加题目到试卷
// 入参：路径参数（id）、请求体（题目ID及分数）
// 流程：解析试卷ID -> 解析并校验请求参数 -> 调用服务层添加题目 -> 处理错误并返回结果
func AddQuestionToPaper(c *gin.Context) {
	// 解析试卷ID
	paperID, err := utils.ParseParamToUint(c, "id")
	if err != nil {
		response.Error(c, http.StatusBadRequest, err.Error())
		return
	}
	// 解析并校验请求参数
	var req dto.AddQuestionToPaperRequest
	if err := utils.BindAndValidate(c, &req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数错误: "+err.Error())
		return
	}
	// 调用服务层添加题目
	paperQuestion, err := services.AddQuestionToPaper(paperID, req)
	if err != nil {
		utils.HandleServiceError(c, err)
		return
	}
	// 返回成功响应
	response.Success(c, gin.H{"paper_question": paperQuestion}, "题目已添加到试卷")
}

// RemoveQuestionFromPaper 从试卷中移除题目
// 入参：路径参数（id、questionId）
// 流程：解析试卷ID和题目ID -> 调用服务层移除题目 -> 处理错误并返回结果
func RemoveQuestionFromPaper(c *gin.Context) {
	// 解析试卷ID和题目ID
	paperID, err := utils.ParseParamToUint(c, "id")
	if err != nil {
		response.Error(c, http.StatusBadRequest, "无效的试卷ID")
		return
	}
	questionID, err := utils.ParseParamToUint(c, "questionId")
	if err != nil {
		response.Error(c, http.StatusBadRequest, "无效的题目ID")
		return
	}
	// 调用服务层移除题目
	err = services.RemoveQuestionFromPaper(paperID, questionID)
	if err != nil {
		utils.HandleServiceError(c, err)
		return
	}
	// 返回成功响应
	response.Success(c, nil, "题目已从试卷中移除")
}

// UpdateQuestionOrder 调整试卷中题目的顺序
// 入参：路径参数（id）、请求体（题目ID及顺序列表）
// 流程：解析试卷ID -> 解析并校验请求参数 -> 调用服务层更新顺序 -> 处理错误并返回结果
func UpdateQuestionOrder(c *gin.Context) {
	// 解析试卷ID
	paperID, err := utils.ParseParamToUint(c, "id")
	if err != nil {
		response.Error(c, http.StatusBadRequest, err.Error())
		return
	}
	// 解析并校验请求参数
	var req dto.UpdateQuestionOrderRequest
	if err := utils.BindAndValidate(c, &req); err != nil {
		response.Error(c, http.StatusBadRequest, "参数格式错误: "+err.Error())
		return
	}
	// 调用服务层更新顺序
	err = services.UpdateQuestionOrder(paperID, req.Questions)
	if err != nil {
		utils.HandleServiceError(c, err)
		return
	}
	// 返回成功响应
	response.Success(c, nil, "题目顺序已更新")
}
